<!DOCTYPE html>
<html>
<head>
    <title>js面向对象-优化jClass函数</title>
    <meta charset="utf-8"/>
    <script src="../../js/jquery-1.10.1.min.js"></script>
    <script src="../../js/json2.js"></script>
    <script>

        Function.prototype.method = function(name, func) {
            // this指向当前函数，也即是typeof(this) === "function"
            this.prototype[name] = func;
            return this;
        };

//        Function.method('inherits', function (parent) {
//            // 关键是这一段：this.prototype = new parent()，这里实现了原型的引用
//            var d = {}, p = (this.prototype = new parent());
//
//            // 只为子类的原型增加uber方法，这里的Closure是为了在调用uber函数时知道当前类的父类的原型（也即是变量 - v）
//            this.method('uber', function uber(name) {
//                // 这里考虑到如果name是存在于Object.prototype中的函数名的情况
//                // 比如 "toString" in {} === true
//                if (!(name in d)) {
//                    // 通过d[name]计数，不理解具体的含义
//                    d[name] = 0;
//                }
//                var f, r, t = d[name], v = parent.prototype;
//                if (t) {
//                    while (t) {
//                        v = v.constructor.prototype;
//                        t -= 1;
//                    }
//                    f = v[name];
//                } else {
//                    // 个人觉得这段代码有点繁琐，既然uber的含义就是父类的函数，那么f直接指向v[name]就可以了
//                    f = p[name];
//                    if (f == this[name]) {
//                        f = v[name];
//                    }
//                }
//                d[name] += 1;
//                // 执行父类中的函数name，但是函数中this指向当前对象
//                // 同时注意使用Array.prototype.slice.apply的方式对arguments进行截断（因为arguments不是标准的数组，没有slice方法）
//                r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
//                d[name] -= 1;
//                return r;
//            });
//            return this;
//        });


        Function.prototype.inherits = function(parent) {
            this.prototype = new parent();
            this.prototype.constructor = this;
            this.prototype.uber = function(name) {
                f = parent.prototype[name];
                return f.apply(this, Array.prototype.slice.call(arguments, 1));
            };
        };

        // 定义Person类
        function Person(name) {
            this.name = name;
        }
        // 定义Person的原型方法
        Person.method("getName", function() {
            return this.name;
        });

        // 定义Employee类
        function Employee(name, employeeID) {
            this.name = name;
            this.employeeID = employeeID;
        }
        // 指定Employee类从Person类继承
        Employee.inherits(Person);
        // 定义Employee的原型方法
        Employee.method("getEmployeeID", function() {
            return this.employeeID;
        });
        Employee.method("getName", function() {
            // 注意，可以在子类中调用父类的原型方法
            return "Employee name: " + this.uber("getName");
        });
        // 实例化子类
        var zhang = new Employee("ZhangSan", "1234");
        console.log(zhang.getName());   // "Employee name: ZhangSan"


    </script>
</head>
<body>

</body>
</html>